# -*- coding: utf-8 -*-
from django.shortcuts import render


from django.http import (HttpResponse, HttpResponseServerError,
                         HttpResponseNotFound, HttpResponseRedirect)
from django.template.response import TemplateResponse
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User

#from mezzanine.core.models import RichText
from mezzanine.pages.models import RichTextPage
from mezzanine.pages.models import Page


from encuesta.models import Puntaje_Encuesta, Puntaje_Punto

from encuesta.utils import ObtenerEvaluaciones, ExisteEvaluacion, ObtenerEvaluacion
from encuesta.utils import IdUsuarioRequest, UsuarioRequest
from encuesta.utils import PuntuacionTotal, NumEvaluaciones
from encuesta.utils import OrdenarPuntos

# para generacion de pdfs
from reportlab.pdfgen import canvas
from django.http import HttpResponse

def DimensionDisplay(request, dimension):
    ''' Pagina que muestra la encuesta de la dimension dada 
    '''
    if dimension == "r":
        return HttpResponseRedirect('/estadisticas_encuesta/')
        
    pages = Page.objects.filter(title__startswith="p_"+dimension)
    richTextPages = []
    paginas = []

    user = UsuarioRequest(request)
    user_id = IdUsuarioRequest(request)

    for page in pages:
        content = RichTextPage.objects.get(id=int(page.id)).content

        # busca puntuacion si existe
        puntuacion = ObtenerEvaluacion(user_id, punto=page.title[2:])
        puntaje = 0
        if puntuacion is not None:
            puntaje = puntuacion.puntuacion
        
        paginas.append({"titulo": page.title,
                        "contenido": content,
                        "puntaje": puntaje,
                        "id_pagina": page.id})

    return TemplateResponse(request, "pages/encuesta_d"+dimension+".html",
                            {"paginas": paginas } )

def Dim1Display(request):
    ''' Pagina de la encuesta de la dimension 1 de la encuesta
    '''
    pages = Page.objects.filter(title__startswith="p_1")
    richTextPages = []
    paginas = []

    user = UsuarioRequest(request)
    user_id = IdUsuarioRequest(request)

    for page in pages:
        content = RichTextPage.objects.get(id=int(page.id)).content

        # busca puntuacion si existe
        puntuacion = ObtenerEvaluacion(user_id, punto=page.title[2:])
        puntaje = 0
        if puntuacion is not None:
            puntaje = puntuacion.puntuacion
        
        paginas.append({"titulo": page.title,
                        "contenido": content,
                        "puntaje": puntaje})

    return TemplateResponse(request, "pages/encuesta_d1.html",
                            {"paginas": paginas } )

def Evaluacion(request, dimension_encuesta):
    ''' Procesa en envio de una evaluacion de la encuesta
    de acreditacion
    '''
    id_usuario = -1
    try:
        id_usuario = request.user.id
        if id_usuario is None:
            id_usuario = 0
    except ObjectDoesNotExist:
        id_usuario = -1

    if id_usuario == 0: # usuario anonimo
        #TODO: Retornar enlace a login
        return HttpResponse('usuario Anonimo, por favor ingrese <a href="/accounts/login">con su cuenta de usuario</a>')

    user = User.objects.get(id=id_usuario)

    for punto, puntuacion in request.POST.items():
        Puntuacion = ObtenerEvaluacion(id_usuario,\
                                       punto=str(punto))
        
        # creando nuevo registro, este caso de da cuando
        # se ha agregado un punto a la encuesta.
        if Puntuacion is None:
            # filtrando primero valores en el request que tengan que ver con
            # la puntuacion, para excluir por ejemplo valores como el
            # token csrf
            if punto != 'csrfmiddlewaretoken':
                P = Puntaje_Encuesta()
                P.user = user
                P.punto = str(punto)
                P.puntuacion = int(str(puntuacion))
                P.save()
        else:
            # modificando registro existente
            Puntuacion.puntuacion = int(str(puntuacion))
            Puntuacion.save()

        # agregando/modificando registro de puntaje para resultados de la encuesta
        try:
            Puntaje = Puntaje_Punto.objects.get(punto=str(punto))
            Puntaje.actualizar(int(str(puntuacion)))
            Puntaje.save()
            #print ("actualizado puntaje:"+str(Puntaje))
        except ObjectDoesNotExist:
            # caso raro cuando se ha recibido un punto que no existia
            '''Puntaje = Puntaje_Punto()
            Puntaje.punto = str(punto)
            Puntaje.actualizar(int(str(puntuacion)))
            Puntaje.save()'''
            # en este caso no se hace nada ya que se supone que antes
            # se han creado registros para cada punto.
            pass
                
    #TODO: retornar Template
    #return TemplateResponse(request, "pages/encuesta_d"+dimension_encuesta+"1.html"
    #{})
    #return DimensionDisplay(request, dimension_encuesta)
    # retornando template referente a la dimension siguiente de la encuesta
    dim_siguiente = ""
    if dimension_encuesta == "1":
        dim_siguiente = "2"
    if dimension_encuesta == "2":
        dim_siguiente = "3"
    if dimension_encuesta == "3":
        dim_siguiente = "4"
    if dimension_encuesta == "4":
        dim_siguiente = "r"
    return DimensionDisplay(request, dim_siguiente)


def EstadisticaEncuesta(request):
    ''' De la tabla puntaje_encuesta obtiene algunas estadisticas de las
    respuestas hechas, retorna ademas el template para que se renderize
    los resultados de las encuestas por cada punto y dimension.
    '''
    puntos = []

    puntajes_d1 = []
    puntajes_d2 = []
    puntajes_d3 = []
    puntajes_d4 = []

    Puntajes = Puntaje_Punto.objects.all()
    for P in Puntajes:
        if P.punto[0] == "1":
            puntajes_d1.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
        if P.punto[0] == "2":
            puntajes_d2.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
        if P.punto[0] == "3":
            puntajes_d3.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
        if P.punto[0] == "4":
            puntajes_d4.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )

    # return ReporteComoPdf("pages/estadistica_encuesta.html",
    #                             {
    #                                 "pagesize" : "A4",
    #                              "puntajes_d1": OrdenarPuntos(puntajes_d1),
    #                              "puntajes_d2": OrdenarPuntos(puntajes_d2),
    #                              "puntajes_d3": OrdenarPuntos(puntajes_d3),
    #                              "puntajes_d4": OrdenarPuntos(puntajes_d4),
    #                             })
            
    return TemplateResponse(request, "pages/estadistica_encuesta.html",
                                {"puntajes_d1": OrdenarPuntos(puntajes_d1),
                                 "puntajes_d2": OrdenarPuntos(puntajes_d2),
                                 "puntajes_d3": OrdenarPuntos(puntajes_d3),
                                 "puntajes_d4": OrdenarPuntos(puntajes_d4),
                                 })

def ReportePdf(request):
    ''' Renderiza un pdf con el reporte basico de la encuesta
    de acreditacion
    '''
    # preparando los datos
    puntos = []
    puntajes_d1 = []
    puntajes_d2 = []
    puntajes_d3 = []
    puntajes_d4 = []

    Puntajes = Puntaje_Punto.objects.all()
    for P in Puntajes:
        if P.punto[0] == "1":
            puntajes_d1.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
        if P.punto[0] == "2":
            puntajes_d2.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
        if P.punto[0] == "3":
            puntajes_d3.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
        if P.punto[0] == "4":
            puntajes_d4.append(
                {"punto": P.punto,
                 "total": P.sumatoria,
                 "num_evaluaciones": P.valoraciones,
                 "porcentaje" : (P.promedio*100)/5,
                 "promedio" : P.promedio
                }
            )
    OrdenarPuntos(puntajes_d1)
    OrdenarPuntos(puntajes_d2)
    OrdenarPuntos(puntajes_d3)
    OrdenarPuntos(puntajes_d4)
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="reporte-acreditacion.pdf"'

    # Create the PDF object, using the response object as its "file."
    p = canvas.Canvas(response)
    
    p.drawString(100, 800, "Reporte - RESULTADOS DE LA ENCUESTA DE ACREDITACIÓN (MERCOSUR) ")
    p.drawString(100, 780, "INGENIERÍA INDUSTRIAL UMSA")
    p.drawString(100, 760, "_______________________________________________________________")

    # dimension 1
    p.drawString(100, 740, "DIMENSIÓN 1")
    p.drawString(70, 720, "Punto")
    p.drawString(140, 720, "Número de Valoraciones")
    p.drawString(300, 720, "Porcentaje de aceptación (%)")

    c = 0
    prom_porcentaje = 0
    for d1 in OrdenarPuntos(puntajes_d1):
        c += 1
        p.drawString(70, 720 - (c*15), str(d1['punto']))
        p.drawString(140,720 - (c*15), str(d1['num_evaluaciones']))
        p.drawString(300, 720 - (c*15), str(d1['porcentaje'])[0:4])
        prom_porcentaje += d1['porcentaje']
    prom_porcentaje /= len(puntajes_d1)
    p.drawString(300, 740, "Promedio aceptación: "+ str(prom_porcentaje)[0:4] +\
                 " %")
    p.showPage() # termina la pagina actual
    
    # dimension 2
    p.drawString(100, 740, "DIMENSIÓN 2")
    p.drawString(70, 720, "Punto")
    p.drawString(140, 720, "Número de Valoraciones")
    p.drawString(300, 720, "Porcentaje de aceptación (%)")
    
    c = 0
    prom_porcentaje = 0
    for d2 in OrdenarPuntos(puntajes_d2):
        c += 1
        if c*15 >= 650:
            # nueva pagina
            p.showPage()

            p.drawString(100, 740, "DIMENSIÓN 2")
            p.drawString(70, 720, "Punto")
            p.drawString(140, 720, "Número de Valoraciones")
            p.drawString(300, 720, "Porcentaje de aceptación (%)")
            c = 1
        p.drawString(70, 720 - (c*15), str(d2['punto']))
        p.drawString(140,720 - (c*15), str(d2['num_evaluaciones']))
        p.drawString(300, 720 - (c*15), str(d2['porcentaje'])[0:4])
        prom_porcentaje += d2['porcentaje']
    prom_porcentaje /= len(puntajes_d2)
    p.drawString(300, 740, "Promedio aceptación: "+ str(prom_porcentaje)[0:4] +\
                 " %")
    p.showPage() # termina pagina actual

    # dimension 3
    p.drawString(100, 740, "DIMENSIÓN 3")
    p.drawString(70, 720, "Punto")
    p.drawString(140, 720, "Número de Valoraciones")
    p.drawString(300, 720, "Porcentaje de aceptación (%)")
    
    c = 0
    prom_porcentaje = 0
    for d3 in OrdenarPuntos(puntajes_d3):
        c += 1
        if c*15 >= 650:
            # nueva pagina
            p.showPage()

            p.drawString(100, 740, "DIMENSIÓN 3")
            p.drawString(70, 720, "Punto")
            p.drawString(140, 720, "Número de Valoraciones")
            p.drawString(300, 720, "Porcentaje de aceptación (%)")
            c = 1
        p.drawString(70, 720 - (c*15), str(d3['punto']))
        p.drawString(140,720 - (c*15), str(d3['num_evaluaciones']))
        p.drawString(300, 720 - (c*15), str(d3['porcentaje'])[0:4])
        prom_porcentaje += d3['porcentaje']
    prom_porcentaje /= len(puntajes_d3)
    p.drawString(300, 740, "Promedio aceptación: "+ str(prom_porcentaje)[0:4] +\
                 " %")
    p.showPage() # termina pagina actual
    
    # dimension 4
    p.drawString(100, 740, "DIMENSIÓN 4")
    p.drawString(70, 720, "Punto")
    p.drawString(140, 720, "Número de Valoraciones")
    p.drawString(300, 720, "Porcentaje de aceptación (%)")
    
    c = 0
    prom_porcentaje = 0
    for d4 in OrdenarPuntos(puntajes_d4):
        c += 1
        if c*15 >= 650:
            # nueva pagina
            p.showPage()

            p.drawString(100, 740, "DIMENSIÓN 4")
            p.drawString(70, 720, "Punto")
            p.drawString(140, 720, "Número de Valoraciones")
            p.drawString(300, 720, "Porcentaje de aceptación (%)")
            c = 1
        p.drawString(70, 720 - (c*15), str(d4['punto']))
        p.drawString(140,720 - (c*15), str(d4['num_evaluaciones']))
        p.drawString(300, 720 - (c*15), str(d4['porcentaje'])[0:4])
        prom_porcentaje += d4['porcentaje']
    prom_porcentaje /= len(puntajes_d4)
    p.drawString(300, 740, "Promedio aceptación: "+ str(prom_porcentaje)[0:4] +\
                 " %")
    p.showPage() # termina pagina actual
        
    # Close the PDF object cleanly, and we're done.
    p.save()
    return response

# la siguiente funcion esta solo de muestra no se utiliza realmente aqui
def page(request, slug, template=u"pages/page.html", extra_context=None):
    """
    Select a template for a page and render it. The request
    object should have a ``page`` attribute that's added via
    ``mezzanine.pages.middleware.PageMiddleware``. The page is loaded
    earlier via middleware to perform various other functions.
    The urlpattern that maps to this view is a catch-all pattern, in
    which case the page attribute won't exist, so raise a 404 then.

    For template selection, a list of possible templates is built up
    based on the current page. This list is order from most granular
    match, starting with a custom template for the exact page, then
    adding templates based on the page's parent page, that could be
    used for sections of a site (eg all children of the parent).
    Finally at the broadest level, a template for the page's content
    type (it's model class) is checked for, and then if none of these
    templates match, the default pages/page.html is used.
    """

    from mezzanine.pages.middleware import PageMiddleware
    if not PageMiddleware.installed():
        raise ImproperlyConfigured("mezzanine.pages.middleware.PageMiddleware "
                                   "(or a subclass of it) is missing from " +
                                   "settings.MIDDLEWARE_CLASSES or " +
                                   "settings.MIDDLEWARE")

    if not hasattr(request, "page") or request.page.slug != slug:
        raise Http404

    # Check for a template name matching the page's slug. If the homepage
    # is configured as a page instance, the template "pages/index.html" is
    # used, since the slug "/" won't match a template name.
    template_name = str(slug) if slug != home_slug() else "index"
    templates = [u"pages/%s.html" % template_name]
    method_template = request.page.get_content_model().get_template_name()
    if method_template:
        templates.insert(0, method_template)
    if request.page.content_model is not None:
        templates.append(u"pages/%s/%s.html" % (template_name,
            request.page.content_model))
    for parent in request.page.get_ascendants(for_user=request.user):
        parent_template_name = str(parent.slug)
        # Check for a template matching the page's content model.
        if request.page.content_model is not None:
            templates.append(u"pages/%s/%s.html" % (parent_template_name,
                request.page.content_model))
    # Check for a template matching the page's content model.
    if request.page.content_model is not None:
        templates.append(u"pages/%s.html" % request.page.content_model)
    templates.append(template)
    return TemplateResponse(request, templates, extra_context or {})


##### Funciones extra de utilidad #########
import csv
import datetime
import io

def Comprobar_bd_ciru(request):
    '''  a partir del archivo datos.csv comprueba que existan usuarios
    y si no existe los crea 
    El orden del csv esperado es:
    id_estudiante;ci;ru;nombre;paterno;materno
    1;9170943;1680926;CRISTIAN ISAAC;AÑAMORO;ALVAREZ
    2;10015481;1714266;JHESSICA JHANET;AGUILAR;CONDORI
    3;8422342;1673676;MARISOL;ACHO;SARZURI
    4;9214862;1679075;SHIRLEY PAMELA;ACHO;YUJRA
    '''
    archivo_csv = "encuesta/datos.csv"
    contenido_csv = []
    
    # lectura de archivo y parseado segun csv y utf-8
    # solucion extraida de https://stackoverflow.com/questions/17245415/read-and-write-csv-files-including-unicode-with-python-2-7#17246997
    with open(archivo_csv,'r') as fin:
        reader=csv.reader(fin)
        for row in reader:
            temp=list(row)
            #fmt=u'{:<15}'*len(temp)
            #print fmt.format(*[s.decode('utf-8') for s in temp])
            temp1=[]
            for s in temp:
                temp1.append(s.decode('utf-8'))
                contenido_csv.append(temp1)
                
    contenido_csv = contenido_csv[1:] # ignorando primera fila
    # insertando cada fila
    for c in contenido_csv:
        # buscando que el usuario no exista
        try:
            user = User.objects.get(username=c[1])
            print ("username: "+c[1]+" ya existe")
        except ObjectDoesNotExist:
            # agregando nuevo usuario
            user = User()
            user.username=c[1] # ci
            user.set_password(c[2]) # ru
            user.first_name=c[3] # nombres
            user.last_name =c[4] + " " + c[5]  # apellidos
            user.is_staff = False
                        
            user.save()
            print ("regsitro agregado:"+str(user))
            # for s in c:
                #     print s
        print ("==")
        # for l in contenido_csv:
        #     print (str(l))
    st = '<head><meta http-equiv="Content-type" content="text/html; charset=utf-8"></head>'
    return HttpResponse(st+str(contenido_csv).decode("utf-8"))

## muy temporal ##
def PoblarPuntajePuntos(request):
    ''' Llena la tabla puntaje puntos con los promedios y
    valoraciones de cada punto de la encuesta
    '''

    try:
        P = Puntaje_Encuesta.objects.all()
        for p in P:
            # buscando puntaje de punto de encuesta
            try:
                # actualizando registro
                puntaje = Puntaje_Punto.objects.get(punto=p.punto)
                    
                puntaje.actualizar(p.puntuacion)
                puntaje.save()
                print("Actualizado registro " + str(puntaje))

            except ObjectDoesNotExist:
                # creando registro
                puntaje = Puntaje_Punto()
                puntaje.punto = p.punto
                puntaje.actualizar(p.puntuacion)
                puntaje.save()
                print("Creando registro :" + str(puntaje))
            
    except ObjectDoesNotExist:
        pass

    # terminado ahora mostrando reportes
    Puntajes = Puntaje_Punto.objects.all()
    return HttpResponse(str(Puntajes))

                    
